#pragma once

#include <QtWidgets/QWidget>
#include <QtWidgets/QVBoxLayout>
#include "bondchart.h"
#include "bondcharttools.h"
#include <widgets/chart/basechart_axis.h>
#include <widgets/chart/basechart_layoutitem.h>
#include <qbprotocol/include/SSQBAModel.h>

namespace qb
{
	enum emPriceModel {
		model_Yeild = 0,//收益率
		model_Clean//净价
	};

	typedef struct _tag_PriceRealTime_tmp {//报价实时
		float		m_Price1;
		float		m_Price2;
		float		m_PriceYeild1; //收益率
		float		m_PriceYeild2;
		float		m_PriceClean1;//净价
		float		m_PriceClean2;
		time_t		m_time;

		_tag_PriceRealTime_tmp() {
			Clear();
		};
		void Clear() {
			m_PriceClean1 = m_PriceYeild1 = m_Price1 = -1000;
			m_PriceClean2 = m_PriceYeild2 = m_Price2 = -1000;
			m_time = 0;
		}
		//return if valid
		bool SetPrice(time_t tTime, const char* prc1, const char* prc2, const char* prcCln1, const char* prcCln2, bool isYeild, bool isTran = false) {
			m_time = tTime;
			bool bValid = false;
			if (isYeild) {
				if (!isTran) {
					if (AddValidData(m_PriceYeild1, prc1)) {
						AddValidData(m_Price1, prc1);
						bValid = true;
					}
					if (AddValidData(m_PriceYeild2, prc2)) {
						AddValidData(m_Price2, prc2);
						bValid = true;
					}
				}
				if (bValid || isTran) {
					bValid = true;
					AddValidData(m_PriceClean1, prcCln1);
					AddValidData(m_PriceClean2, prcCln2);
				}
			}
			else {
				if (AddValidData(m_PriceClean1, prcCln1)) {
					AddValidData(m_Price1, prcCln1);
					bValid = true;
				}
				if (AddValidData(m_PriceClean2, prcCln2)) {
					AddValidData(m_Price2, prcCln2);
					bValid = true;
				}
				if (bValid && !isTran) {
					AddValidData(m_PriceYeild1, prc1);
					AddValidData(m_PriceYeild2, prc2);
				}
			}
			return bValid;
		}

		bool AddValidData(float& fPrc, const char* cPrc) {
			if (strlen(cPrc) > 0 && atof(cPrc) > 0.001) {
				fPrc = atof(cPrc);
				return true;
			}
			return false;
		}
		const bool operator < (const _tag_PriceRealTime_tmp& obj) const
		{
			return (m_time < obj.m_time);
		}
	}PriceRealTime, * PPriceRealTime;

	class PriceRealTimeList {
	public:
		std::list<PriceRealTime> m_List;
	public:
		PriceRealTimeList() { m_nModel = model_Yeild; };
		bool  IsYeildModel() { return m_nModel == (int)model_Yeild; }
		void  Clear() { m_List.clear(); }
		void  Insert(const PriceRealTime& item) { m_List.push_back(item); }
		void  SetModel(int nModel) { m_nModel = nModel; }
		bool  ChangeModel(int nModel) {
			if (m_nModel == nModel) return false;
			m_nModel = nModel;
			for (std::list<PriceRealTime>::iterator itr = m_List.begin(); itr != m_List.end(); itr++) {
				if (m_nModel == model_Yeild) {
					itr->m_Price1 = itr->m_PriceYeild1;
					itr->m_Price2 = itr->m_PriceYeild2;
				}
				else {
					itr->m_Price1 = itr->m_PriceClean1;
					itr->m_Price2 = itr->m_PriceClean2;
				}
			}
			return true;
		}

	private:
		int  m_nModel;
	};

    class BondQuoteBrokerChart
		: public QWidget
		, public BaseChartCustomAxisGrid
		, public BaseChartCustomTextElement
    {
		Q_OBJECT
    public:
		BondQuoteBrokerChart(QWidget* parent = nullptr);
		~BondQuoteBrokerChart();

		enum emPrice {
			prc_Yeild = 0,//显示为收益率
			prc_Clean,//显示为净价
			prc_Max
		};

		void setBondInfo(const CBondInfo* bondinfo);
		int getMarketType();
		void loadKLineData(xQBABrokerKlineDayList_c* pData);
		void loadRealTimeData(xQBMarketStreamList_c* pData);
		void createChart();
		void refreshData();
		void setSelect(int select);
		void setAbCheck(int check);
		void setPriceType(emPrice prcType);
		int getPriceType() { return m_nPrcType; }
		void setMarketType(em_BrokerKinds emCurType);
		void setLeftDrag(double ratio);
		void setRightDrag(double ratio);
		void setCentralDrag(double ratio1, double ratio2);

		PriceKLineList* GetPriceKLineList();
		PriceRealTimeList* GetPriceRealTimeList();
		PriceRealTimeList* GetPriceRealTimeList2();

		BaseChartDragBarElement* dragBar() { return bcde; }

		// BaseChartCustomAxisGrid
		virtual bool drawGridXLines(BaseChartPainter* painter);
		virtual bool drawGridYLines(BaseChartPainter* painter);

		// BaseChartCustomTextElement
		virtual bool customDraw(BaseChartPainter* painter, const QRect& rect);
	signals:
		void mouseDoubleClick(QWidget*);
	protected:
		void inputKLineData(xQBABrokerKlineDayList_c* pData);
		void inputRealTimeData(xQBMarketStreamList_c* pData);
		void GetShowLimit(double fMinXShow, double fMaxXShow, double& fMinYShow, double& fMaxYShow);
		void GetShowLimit1(double fMinXShow, double fMaxXShow);
		void GetShowLimit2(double fMinXShow, double fMaxXShow);
		void drawGridXLines1(BaseChartPainter* painter);
		void drawGridXLines2(BaseChartPainter* painter);
		void drawMouseMoveLine(BaseChartPainter* painter);
		int GetKLineIndex(int nIndex, std::list<PriceKLine>::iterator& it);
		QString	GetKLineDateString(std::list<PriceKLine>::iterator& it);
		QString	strInt2DateInTable(UINT nDate);
		void CheckSelectMode(xQBMarketStreamList_c* pRealTime);
		bool IsYeildModel() { return m_nPrcType == (int)prc_Yeild; }
		int GetPriceRealTimeIndex(int nIndex, std::list<PriceRealTime>::iterator& it);
		QString GetPriceRealTimeString(std::list<PriceRealTime>::iterator& it);
		bool AddTipsFormat(float fYeild, float fClean, bool bBid, QString& sTps);
		bool NeedToFilter();
		void FilterAbnormalVal(void);
		void FilterOneVerify(std::list<PriceRealTime>::const_iterator iter, const std::list<PriceRealTime>& lstPriceRealTime, int nPosition, bool& prc1, bool& prc2);
		/*单边判断Bid ofr  遇到空值跳过*/
		bool FilterOneVerifySingle(std::list<PriceRealTime>::const_iterator iter, const std::list<PriceRealTime>& lstPriceRealTime, int nPosition, bool bBid);
		bool AbnormalVal(float curPrice, float price1);
		int FloatCompare(double f) const;
		double getXPos_Value(double value);

		void paintEvent(QPaintEvent* event) override;
		void leaveEvent(QEvent* event) override;

		Q_SLOT void onMouseMove(QMouseEvent* event);

	private:
		BaseChartCustomPlot*		customPlot		= nullptr;
		QVBoxLayout*				verticalLayout	= nullptr;
		BaseChartDragBarElement*	bcde			= nullptr;

		CBondInfo*					mBondInfo		= nullptr;
		PriceKLineList				m_DataKLineBroker;//报价，成交日线
		PriceKLineList				m_DataKLineCFETS;
		PriceKLineList				m_DataKLineExchange;
		PriceRealTimeList			m_DataRealTimeBroker;//实时报价
		PriceRealTimeList			m_DataRealTimeCFETS;
		PriceRealTimeList			m_DataRealTimeExchange;
		PriceRealTimeList			m_quotesFiltered; //已过滤的实时报价

		int							m_nBtnSelect;
		int							m_nPrcType;
		int							m_nMarketType;
		int							m_nHotPoint;
		int							m_nRealBegin;
		int							m_nRealEnd;
		bool						m_bCheckFilter;
		bool						m_bShowLine1;
		bool						m_bShowLine2;
		double						m_dMinX;
		double						m_dMaxX;
		double						m_dMinY;
		double						m_dMaxY;
		double						m_dOriginMinX;
		double						m_dOriginMaxX;
		double						m_dDragLeft;
		double						m_dDragRight;
    };
}

